import os
import base64

from pytz import common_timezones, utc
from django.core.mail.backends.smtp import EmailBackend
from django.contrib.auth.tokens import default_token_generator
from django.template import engines
from django.shortcuts import reverse
from django.core.mail import send_mail
from django.utils.html import strip_tags

# a Global HttpRequest.
_request = None


def get_request():
    return _request


def is_demo():
    if bool(int(os.getenv('DEMO_MODE', 0))):
        return True
    return False


def truncatechars(value, length=0):
    value = str(value)
    value_length = len(value)

    if not value_length <= length:
        return f"{value[:length]}..."
    return value


def get_client_ip(req):
    x_forwarded_for = req.META.get('HTTP_X_FORWARDED_FOR')

    if x_forwarded_for:
        return x_forwarded_for.split(',')[0]
    return req.META.get('REMOTE_ADDR')


def get_timezone_list():
    return zip(common_timezones, common_timezones)


def get_default_timezone():
    return utc


def parse_bool(value):
    if str(value).lower() == 'true':
        return True
    return False


class CustomEmailBackend(EmailBackend):

    def __init__(self, host=None, port=None, username=None, password=None, use_tls=None, use_ssl=None, **kwargs):
        from settings.utils import get_setting

        host = get_setting('SMTP_HOST')
        port = get_setting('SMTP_PORT')
        username = get_setting('SMTP_USER')
        password = get_setting('SMTP_PASS')

        use_tls = True if get_setting('MAIL_ENCRYPTION') == 'TLS' else False
        use_ssl = not use_tls

        super().__init__(host=host, port=port, username=username, password=password,
                         use_tls=use_tls, use_ssl=use_ssl, **kwargs)


def mail_wrapper(mail_content=None):
    from settings.utils import get_setting

    header = get_setting('EMAIL_HEADER')
    footer = get_setting('EMAIL_FOOTER')
    content = mail_content

    page = f"""
<html>
    <head></head>
    <body>
        {header}
        {content}
        {footer}
    </body>
</html>
"""
    return page


def send_user_activation_mail(user, req):
    # Don't send mails on the demo mode.
    if is_demo():
        return True

    from settings.utils import get_setting

    # Send activation mail
    user_token = default_token_generator.make_token(user)
    account_activation_link = "%s://%s%s" % (req.scheme, req.get_host(), reverse('activation', kwargs={
        'uid64': base64.urlsafe_b64encode(str(user.pk).encode()).decode(),
        'token': user_token
    }))

    # send an email & redirect.
    email_context = {
        'user': user,
        'SITE_NAME': get_setting('SITE_NAME'),
        'USER_USERNAME': user.username,
        'USER_EMAIL': user.email,
        'USER_TOKEN': user_token,
        'ACCOUNT_ACTIVATION_LINK': account_activation_link
    }

    # Rendering email template.
    email_template = engines['django'].from_string(
        mail_wrapper(get_setting('EMAIL_NEW_ACCOUNT')))
    email_message = email_template.render(email_context, req)

    subject = '%s: Account Activation' % get_setting('SITE_NAME')
    from_email = "%s <%s>" % (get_setting(
        'SITE_NAME'), get_setting('SMTP_USER'))  # SMTP_USER

    return send_mail(subject, strip_tags(email_message), from_email, [
        user.email], html_message=email_message)


def send_user_reset_password_mail(user, req):
    # Don't send mails on the demo mode.
    if is_demo():
        return True

    from settings.utils import get_setting

    user_token = default_token_generator.make_token(user)
    reset_password_link = "%s://%s%s" % (req.scheme, req.get_host(), reverse('reset', kwargs={
        'uid64': base64.urlsafe_b64encode(str(user.pk).encode()).decode(),
        'token': user_token
    }))

    # send an email & redirect.
    email_context = {
        'user': user,
        'SITE_NAME': get_setting('SITE_NAME'),
        'USER_USERNAME': user.username,
        'USER_EMAIL': user.email,
        'USER_TOKEN': user_token,
        'RESET_PASSWORD_LINK': reset_password_link
    }

    # Rendering email template.
    email_template = engines['django'].from_string(
        mail_wrapper(get_setting('EMAIL_RESET_PASSWORD')))
    email_message = email_template.render(email_context, req)

    subject = '%s: Reset Password' % get_setting('SITE_NAME')
    from_email = "%s <%s>" % (get_setting(
        'SITE_NAME'), get_setting('SMTP_USER'))  # SMTP_USER

    return send_mail(subject, strip_tags(email_message), from_email, [
        user.email], html_message=email_message)
